#include "GAF_Graphics.h"
#include "GAF_Face.h"

namespace GAF
{
	NotRender Graphics::m_NothingRender;

	UINT Graphics::m_nID = 0;
	UINT Graphics::GetID()
	{
		return m_nID++;
	}

	Graphics::Graphics()
	{
		static char _szGraphicsName[20];
		_MEMSET(_szGraphicsName, 0, sizeof(_szGraphicsName));
		_SPRINTF(_szGraphicsName, "G_%d", GetID());

		m_nGType                = GRAPHICS_UNKNOW;
		ATTRIB(GraphicsName)    = _szGraphicsName;
		ATTRIB(Visible)         = true;
		ATTRIB(Location)        = GAF_POINT_ORIGIN;
		ATTRIB(Through)         = THROUGH_NONE;
		ATTRIB(Size)            = GAF_SIZE_ZERO;
		ATTRIB(Anchor)          = 0;
		ATTRIB(AnchorOffset)    = GAF_POINT_ORIGIN;
		ATTRIB(Alpha)           = GAF_ALPHA_DEFAULT;
		ATTRIB(Angle)           = GAF_ANGLE_DEFAULT;
		ATTRIB(Zoom)            = GAF_ZOOM_DEFAULT;
		ATTRIB(ZoomX)           = GAF_ZOOM_DEFAULT;
		ATTRIB(ZoomY)           = GAF_ZOOM_DEFAULT;
		m_pgGroup               = NULL;
		m_isIgnoreSize          = false;
		m_pRender               = &m_NothingRender;
	}

	Graphics::~Graphics()
	{
	}

	bool Graphics::OnPreRender(GAF_CGraphics* pGraphics)
	{
		if(m_pgGroup != NULL)
			return m_pgGroup->OnPreRender(this);

		return true;
	}

	void Graphics::SetGraphicsName(_STRING strGraphicsName)
	{
		if(ATTRIB(GraphicsName).substr(0, 2) == "G_")
			ATTRIB(GraphicsName) = strGraphicsName;
	}

	void Graphics::SetLocation(int nX, int nY)
	{
		ATTRIB(Location).Set(nX, nY);
	}

	void Graphics::SetLocation(float fX, float fY, Graphics* pgFrame)
	{
		int nWidth = 0;
		int nHeight = 0;

		if(pgFrame != NULL)
		{
			nWidth = pgFrame->GetSize().nWidth;
			nHeight = pgFrame->GetSize().nHeight;
		}
		else if(m_pgGroup != NULL)
		{
			nWidth = m_pgGroup->GetSize().nWidth;
			nHeight = m_pgGroup->GetSize().nHeight;
		}
		else
		{
// 			nWidth = THE_PLATFORM->GetScreenWidth();
// 			nHeight = THE_PLATFORM->GetScreenHeight();
		}

		ATTRIB(Location).Set((int)(nWidth * fX), (int)(nHeight * fY));
	}

	void Graphics::SetAnchor(int nX, int nY)
	{
		ATTRIB(Anchor) = 0;
		SetAnchorOffset(nX, nY);
	}

	void Graphics::SetAnchor(float fX, float fY)
	{
		ATTRIB(Anchor) = 0;
		SetAnchorOffset((int)(ATTRIB(Size).nWidth * fX), (int)(ATTRIB(Size).nHeight * fY));
	}

	void Graphics::SetAnchorOffset(int nX, int nY)
	{
		ATTRIB(AnchorOffset).nX = nX;
		ATTRIB(AnchorOffset).nY = nY;
	}

	void Graphics::SetSize(unsigned int nWidth, unsigned int nHeight)
	{
		ATTRIB(Size).nWidth = nWidth;
		ATTRIB(Size).nHeight = nHeight;
	}

	void Graphics::SetRender(Renderable* pRender)
	{
		m_pRender = pRender;
	}

	bool Graphics::GetScreenVisible()
	{
		if(ATTRIB(Visible) && m_pgGroup != NULL)
			return m_pgGroup->GetScreenVisible();
		else
			return ATTRIB(Visible);
	}

	int Graphics::GetScreenPosX()
	{
		int _nGroupX;
		double _dGroupZoom;
		_nGroupX = 0;
		_dGroupZoom = 1.0f;

		if(m_pgGroup != NULL)
		{
			_dGroupZoom = m_pgGroup->GetScreenZoom();

			_nGroupX = m_pgGroup->GetScreenPosX();
			_nGroupX += m_pgGroup->GetAnchorOffset().nX;

			if((m_pgGroup->GetAnchor() & ANCHOR_HMASK) == ANCHOR_LEFT) {}
			else if((m_pgGroup->GetAnchor() & ANCHOR_HMASK) == ANCHOR_HCENTER)
				_nGroupX -= m_pgGroup->GetScreenSizeW() >> 1;
			else if((m_pgGroup->GetAnchor() & ANCHOR_HMASK) == ANCHOR_RIGHT)
				_nGroupX -= m_pgGroup->GetScreenSizeW();
		}

		return (int)(ATTRIB(Location).nX * _dGroupZoom) + _nGroupX;
	}

	int Graphics::GetScreenPosY()
	{
		int _nGroupY;
		double _dGroupZoom;
		_nGroupY = 0;
		_dGroupZoom = 1.0f;

		if(m_pgGroup != NULL)
		{
			_dGroupZoom = m_pgGroup->GetScreenZoom();

			_nGroupY = m_pgGroup->GetScreenPosY();
			_nGroupY += m_pgGroup->GetAnchorOffset().nY;

			if((m_pgGroup->GetAnchor() & ANCHOR_VMASK) == ANCHOR_TOP) {}
			else if((m_pgGroup->GetAnchor() & ANCHOR_VMASK) == ANCHOR_VCENTER)
				_nGroupY -= m_pgGroup->GetScreenSizeH() >> 1;
			else if((m_pgGroup->GetAnchor() & ANCHOR_VMASK) == ANCHOR_BUTTON)
				_nGroupY -= m_pgGroup->GetScreenSizeH();
		}

		return (int)(ATTRIB(Location).nY * _dGroupZoom) + _nGroupY;
	}

	int Graphics::GetScreenSizeW()
	{
		return (int)((double)(GetSize().nWidth) * GetScreenZoom());
	}

	int Graphics::GetScreenSizeH()
	{
		return (int)((double)(GetSize().nHeight) * GetScreenZoom());
	}

	ThroughType Graphics::GetScreenThrough()
	{
		if(GetThrough() != THROUGH_BOTH && m_pgGroup != NULL)
		{
			if(GetThrough() == THROUGH_NONE)
				return m_pgGroup->GetScreenThrough();

			else if(m_pgGroup->GetScreenThrough() == THROUGH_NONE)
				return GetThrough();

			else if(GetThrough() != m_pgGroup->GetScreenThrough())
				return THROUGH_BOTH;

			else
				return GetThrough();
		}
		else
			return GetThrough();
	}


	BYTE Graphics::GetScreenAlpha()
	{
		static BYTE bAlpha;
		if(GetAlpha() > 0 && m_pgGroup != NULL)
		{
			bAlpha = m_pgGroup->GetScreenAlpha();
			if(bAlpha == 255)
				return GetAlpha();
			else
				return (BYTE)((GetAlpha() * bAlpha) >> 8);
		}
		else
			return GetAlpha();
	}

	double Graphics::GetScreenAngle()
	{
		if(m_pgGroup != NULL)
			return GetAngle() + m_pgGroup->GetScreenAngle();
		else
			return GetAngle();
	}

	double Graphics::GetScreenZoom()
	{
		if(m_pgGroup != NULL)
			return GetZoom() * m_pgGroup->GetScreenZoom();
		else
			return GetZoom();
	}

	double Graphics::GetScreenZoomX()
	{
		if(m_pgGroup != NULL)
			return GetZoomX() * m_pgGroup->GetScreenZoomX() * GetScreenZoom();
		else
			return GetZoomX() * GetScreenZoom();
	}

	double Graphics::GetScreenZoomY()
	{
		if(m_pgGroup != NULL)
			return GetZoomY() * m_pgGroup->GetScreenZoomY() * GetScreenZoom();
		else
			return GetZoomY() * GetScreenZoom();
	}

	Bundle& Graphics::Information()
	{
		return m_Information;
	}

	int Graphics::GetGType()
	{
		return m_nGType;
	}

	void Graphics::DockGroup(Graphics* pgGroup)
	{
		if(pgGroup != NULL && m_pgGroup != NULL)
		{
			((Face*)m_pgGroup)->RemoveGraphics(this);
		}

		m_pgGroup = pgGroup;
	}

	Graphics* Graphics::GetDockGroup()
	{
		return m_pgGroup;
	}

	void Graphics::IgnoreSize()
	{
		m_isIgnoreSize = true;
	}

	bool Graphics::IsIgnoreSize()
	{
		return m_isIgnoreSize;
	}
}
